package com.chineseall.app.service;

import java.util.Map;

import javax.annotation.PostConstruct;
import javax.annotation.Resource;

import jmind.core.redis.SingleJedis;
import jmind.core.support.LogUtil;
import jmind.core.util.DataUtil;
import jmind.resource.zk.ZKProperties;

import org.springframework.stereotype.Service;

import redis.clients.jedis.JedisPubSub;

import com.alibaba.fastjson.JSON;
import com.chineseall.app.AppConst;
import com.chineseall.app.MTypes;
import com.chineseall.app.pojo.mongo.MMessage;
import com.chineseall.app.ws.SendMessage;
import com.chineseall.rebirth.api.RebirthApiFactory;
import com.chineseall.rebirth.api.helper.Const;
import com.chineseall.rebirth.api.pojo.BusEvent;
import com.chineseall.rebirth.api.pojo.User;
import com.chineseall.rebirth.api.service.Callback;
import com.chineseall.rebirth.api.service.IBusService;
import com.chineseall.rebirth.api.service.IUserService;
import com.chineseall.rebirth.bridge.pojo.Book;
import com.chineseall.rebirth.bridge.service.ZedisService;
import com.mongodb.BasicDBObject;
import com.mongodb.DBObject;

@Service
public class EventService {
    @Resource
    private ZedisService zedisService;

    final IUserService userService = RebirthApiFactory.getFactory().getApiService(IUserService.class);

    public void startup() {
        System.out.println("startup event");
        final Callback callback = new Callback() {

            @Override
            public boolean doIt(BusEvent event) {
                return doEvent(event);
            }

        };
        IBusService busService = RebirthApiFactory.getFactory().getApiService(IBusService.class);
        // 书被收藏，通知作者
        busService.subscribe(Const.EventType.bookshelf.name(), true, callback);
        // 用户行为，送鲜花，盖章，凹凸票，投贵宾
        busService.subscribe(Const.EventType.behavior.name(), true, callback);
        // 评论
        busService.subscribe(Const.EventType.comment.name(), true, callback);
        //        // 创建新章节
        //        busService.subscribe(Const.EventType.createChapter.name(), true, new Callback() {
        //
        //            @Override
        //            public boolean doIt(BusEvent event) {
        //                LogUtil.debug("createChapter=" + event.demark().toString());
        //                LogUtil.debug(event.toString());
        //                return true;
        //            }
        //
        //        });

    }

    @PostConstruct
    public void startSubscribe() {
        System.out.println("startSubscribe event subscribe");
        final String hosts = ZKProperties.getInstance().getProperty("redis.bus.host");
        // 超时时间，单位秒，默认20
        int timeout = DataUtil.toInt(ZKProperties.getInstance().getProperty("redis.bus.timeout", "30"));
        final SingleJedis jedis = new SingleJedis(hosts, timeout);
        new Thread(new Runnable() {

            @Override
            public void run() {
                jedis.getResource().psubscribe(new JedisPubSub() {

                    @Override
                    public void onUnsubscribe(String channel, int subscribedChannels) {
                        // TODO Auto-generated method stub

                    }

                    @Override
                    public void onSubscribe(String channel, int subscribedChannels) {
                        // TODO Auto-generated method stub

                    }

                    @Override
                    public void onPUnsubscribe(String pattern, int subscribedChannels) {
                        // TODO Auto-generated method stub

                    }

                    @Override
                    public void onPSubscribe(String pattern, int subscribedChannels) {
                        // TODO Auto-generated method stub

                    }

                    @Override
                    public void onPMessage(String pattern, String channel, String message) {
                        try {
                            BusEvent event = JSON.parseObject(message, BusEvent.class);
                            doEvent(event);
                            // LogUtil.debug(event.toString());
                        } catch (Exception e) {
                            e.printStackTrace();
                        }

                    }

                    @Override
                    public void onMessage(String channel, String message) {
                        // TODO Auto-generated method stub

                    }
                }, Const.IBUS_EVENT + "*");

            }
        }).start();

        System.out.println("startSubscribe event subscribe over..");
    }

    private void send(String topic, int uid, MMessage message) {
        SendMessage.send(uid, message);
    }

    public boolean doEvent(BusEvent event) {
        if (Const.EventType.bookshelf.name().equals(event.getTopic())) {
            int bookId = event.getPassenger();
            Book book = zedisService.getBook(bookId);
            if (book == null || book.getAuthor_id() == null) {
                LogUtil.err("EventService getbook is null id=" + bookId);
                return true;
            }
            int uid = book.getAuthor_id();
            MMessage message = new MMessage();
            message.mtype(MTypes.NOTIFY_301);
            message.url("DetailWork");
            message.title(AppConst.TITLE);
            message.body(AppConst.BODY_BOOKSELF);
            User user = userService.getByUid(event.getDriver());
            if (user != null)
                message.summary(String.format(AppConst.SUMMARY_BOOKSELF, user.getNickName(), book.getBookName()));

            DBObject param = new BasicDBObject();
            param.put("bookId", bookId);
            message.param(param);
            send(event.getTopic(), uid, message);
            return true;

        } else if (Const.EventType.behavior.name().equals(event.getTopic())) {
            Map<String, Object> mark = event.demark();
            int bookId = event.getPassenger();
            Book book = zedisService.getBook(bookId);
            int uid = book.getAuthor_id();
            MMessage message = new MMessage();
            message.mtype(MTypes.NOTIFY_301);
            message.url("DetailWork");
            message.title(AppConst.TITLE);
            String body = "";
            String summary = "";
            String type = (String) mark.get("type");
            if ("flower".equalsIgnoreCase(type)) {
                body = AppConst.BODY_FLOWER;
                summary = AppConst.SUMMARY_FLOWER;
            } else if ("gb".equalsIgnoreCase(type)) {
                body = AppConst.BODY_GB;
                summary = AppConst.SUMMARY_GB;
            } else if ("pm".equalsIgnoreCase(type)) {
                body = AppConst.BODY_PM;
                summary = AppConst.SUMMARY_PM;
            } else if ("pk".equalsIgnoreCase(type)) {
                Integer value = (Integer) mark.get("value");
                if (value == null || value > 0) {
                    body = AppConst.BODY_PK;
                    summary = AppConst.SUMMARY_PK;
                } else {
                    body = AppConst.BODY_PK_1;
                    summary = AppConst.SUMMARY_PK_1;
                }

            }

            message.body(body);
            User user = userService.getByUid(event.getDriver());
            if (user != null)
                message.summary(String.format(summary, user.getNickName(), book.getBookName()));
            DBObject param = new BasicDBObject();
            param.put("bookId", bookId);
            message.param(param);
            send(event.getTopic(), uid, message);
            return true;

        } else if (Const.EventType.comment.name().equals(event.getTopic())) {

            try {
                int bookId = event.getPassenger();
                Book book = zedisService.getBook(bookId);
                User user = userService.getByUid(event.getDriver());
                Map<String, Object> mark = event.demark();
                MMessage message = new MMessage();
                message.mtype(MTypes.NOTIFY_301);
                message.title(AppConst.TITLE);
                DBObject param = new BasicDBObject();
                param.put("bookId", bookId);
                Integer uid = (Integer) mark.get("ruid");
                if (uid == null) { // 没有ruid ，是评论，通知作者         
                    uid = book.getAuthor_id();
                    message.url("Discuss");
                    message.body("你的大作收到了1条评论。");
                    message.summary(String.format(AppConst.SUMMARY_COMMENT, user.getNickName(), book.getBookName(),
                            mark.get("content")));
                } else {
                    param.put("commentId", mark.get("rid"));
                    param.put("userId", uid);
                    param.put("nickName", userService.getByUid(uid).getNickName());
                    message.url("Replies");
                    message.body("你的评论收到了1条回复。");
                    message.summary(String.format(AppConst.SUMMARY_COMMENT_REPLAY, user.getNickName(),
                            book.getBookName(), mark.get("content")));
                }

                message.param(param);
                send(event.getTopic(), uid, message);

            } catch (Exception e) {
                e.printStackTrace();
            }
            return true;

        }

        return false;

    }

}
